package org.example.algorithm;

import java.util.Collection;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.springframework.stereotype.Service;

/**
 * sharding jdbc集成hash取模分片算法
 *
 * @author zhangxingpeng
 */
@Slf4j
@Service
public class HashModShardingAlgorithm implements PreciseShardingAlgorithm<String> {
    /**
     * 分片数量
     */
    private static Integer shardingCount = 5;

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
        String certNo = shardingValue.getValue();
        if (certNo == null || "".equals(certNo.trim())) {
            throw new UnsupportedOperationException("certNo is null");
        }
        for (String each : availableTargetNames) {
            if (each.endsWith(String.valueOf(hashShardingValue(certNo)))) {
                log.info("- table name : {}",each);
                return each;
            }
        }
        return null;
    }

    /**
     * 计算分表后缀
     *
     * @param shardingValue
     * @return
     */
    public static long hashShardingValue(final Comparable<?> shardingValue) {
        return (Math.abs((long) shardingValue.hashCode())) % shardingCount;
    }

    public static void main(String[] args) {
        HashModShardingAlgorithm hashModShardingAlgorithm = new HashModShardingAlgorithm();
        for(int i=123;i<123+30;i++){
            System.out.println(i+" "+hashModShardingAlgorithm.hashShardingValue(i+"") % 30);
        }
    }
}
